<template>
  <el-drawer
    v-model="drawerInfo.isShow"
    title="修改meta"
    :with-header="false"
    :modal="true"
    size="450px"
  >
    <!--表单-->
    <el-tabs type="border-card" @tab-click="tabClick">
      <el-tab-pane label="基础">
        <!--基础属性-->
        <nf-form
          v-form-drag="baseFormProps"
          :model="mainMeta"
          v-bind="baseFormProps"
        >
        </nf-form>
      </el-tab-pane>
      <el-tab-pane label="扩展">
        <!--扩展属性-->
        <component
          :is="tabComp.extend"
          v-bind="extendProps"
          :mainMeta="mainMeta"
          :miniMeta="extendMiniMeta"
        ></component>
      </el-tab-pane>
      <el-tab-pane label="验证">
        <component
          :is="tabComp.rule"
          :mainMeta="mainMeta"
          :miniMeta="extendMiniMeta"
        ></component>
      </el-tab-pane>
      <el-tab-pane label="导出">
        模板
        <el-input :rows="4" v-model="extendProps.temp.html" type="textarea" />
        属性：
        <object-format :model="miniMeta" :name="extendProps.temp.name" />
      </el-tab-pane>
    </el-tabs>
  </el-drawer>
</template>

<script>
import { reactive, ref, watch, defineComponent } from 'vue'
// import { nfForm, formItem } from '../map'
import { createColDefValue } from './miniMeta'
import dayjs from 'dayjs'

// 基础属性表单的 meta
import item_base from '../json/item-base.json'

// 格式化
import objectFormat from '../json-format/json-format.vue'

import rule from './rule.vue'
import rule_10 from './extend-text.vue'
import rule_11 from './extend-number.vue'
import rule_12 from './extend-date.vue'
import rule_13 from './extend-time.vue'
import rule_14 from './extend-file.vue'
import rule_15 from './extend-checks.vue'
import rule_16 from './extend-select.vue'

window._dayjs = dayjs

// 延迟加载
const _tabComp = {
  rule: rule, // defineAsyncComponent(() => import('./rule.vue')), // 设置验证规则
  10: rule_10, // defineAsyncComponent(() => import('./extend-text.vue')), // 扩展属性
  11: rule_11, // defineAsyncComponent(() => import('./extend-number.vue')),
  12: rule_12, //  defineAsyncComponent(() => import('./extend-date.vue')),
  13: rule_13, //  defineAsyncComponent(() => import('./extend-time.vue')),
  14: rule_14, //  defineAsyncComponent(() => import('./extend-file.vue')),
  15: rule_15, //  defineAsyncComponent(() => import('./extend-checks.vue')),
  16: rule_16, //  defineAsyncComponent(() => import('./extend-select.vue'))
}

// 不删除的特殊属性
const teshu = [
  'controls-position',
  'clearable',
  'validate_event',
  'show_word_limit'
]

// 创建精简的 meta
/**
 * 基础属性，完整
 * 扩展属性，完整
 * 精简属性 = 基础属性 + 扩展属性 - 不需要的属性
 * 属性默认值
 */
const creatMiniMeta = (mainMeta, extendMiniMeta, miniMeta, baseDefaultValue) => {
  // 清空 miniMeta 的属性
  for (const key in miniMeta) {
    delete miniMeta[key]
  }

  // 遍历 mainMeta
  for (const key in mainMeta) {
    // 同步属性值
    miniMeta[key] = mainMeta[key]

    // 和默认值相同的话，清除
    if (mainMeta[key] === baseDefaultValue[key]) {
      if (!teshu.includes(key)) { // 不是特例
        // 和默认值相等，去掉属性
        delete miniMeta[key]
      }
    }
  }

  // 遍历 extendMiniMeta
  miniMeta.extend = {}
  for (const key in extendMiniMeta) {
    // 同步属性值
    if (key === 'optionList') {
      // 设置给基础属性
      miniMeta.optionList = extendMiniMeta.optionList
    } else {
      // 设置给扩展属性
      miniMeta.extend[key] = extendMiniMeta[key]
    }
  }
  
  // 删除不需要的属性
  // delete miniMeta.kind
  delete miniMeta.extend.controlType
  if (Object.keys(miniMeta.extend).length === 0) {
    delete miniMeta.extend
  }

}

export default defineComponent({
  name: 'el-meta-help-text',
  inheritAttrs: false,
  components:{
    objectFormat

  },
  props: {
    meta: Object, // 基础控件的属性，传递过来进行维护
    drawerInfo: Object // 操作抽屉的展开与合拢
  },
  setup(props) {
    // 传递来的，要维护的控件属性
    const reMeta = props.meta

    // 扩展属性的精简属性
    const extendMiniMeta = reactive({})

    // 基础属性的 meta
    const mainMeta = reactive({})
    mainMeta.colName = reMeta.colName
    mainMeta.controlType = reMeta.controlType
    mainMeta.kind = Math.floor(reMeta.kind / 10)

    const extendMeta = ref({}) // 扩展属性的 meta
    const miniMeta = reactive({}) // 基础 + 扩展 - 默认属性 = 返回的 meta
  
    // 延迟加载组件
    const tabComp = reactive({
      master: '',
      extend: '',
      rule: '',
      output: ''
    })

    // 标签被单击
    const tabClick = (tab) => {
      // console.log('tab', tab)
      switch (tab.index) {
        case '1': // 扩展
          tabComp.extend = _tabComp[mainMeta.kind]
          break
        case '2': // 验证
          tabComp.rule = _tabComp.rule
          break
        case '3': // 导出
          tabComp.sub = _tabComp.sub
          break
      }
    }
    // 监听
    watch(() => mainMeta.kind, () => {
      tabComp.extend = _tabComp[mainMeta.kind]
    })

    // 基础属性的表单需要的 meta，创建表单用
    const baseFormProps = reactive(item_base)
    // 基础属性的默认值
    const baseDefaultValue = createColDefValue(baseFormProps.itemMeta)

    // 返回模板
    const extendProps = reactive({
      temp: {
        name: '',
        html: ''
      }
    })

    // 监听变化，设置精简 meta
    watch([mainMeta, extendMiniMeta], () => {
      creatMiniMeta(mainMeta, extendMiniMeta, miniMeta, baseDefaultValue)
    }, {immediate: true})

    // 监听属性变化，更新内部 meta
    let timeout = null
    watch(props.meta, (_meta) => {
      clearTimeout(timeout)

      timeout = setTimeout(() => {
        for (const key in props.meta) {
          // 更新基础属性
          if (typeof mainMeta[key] !== 'undefined') mainMeta[key] = props.meta[key]
          // 更新扩展属性
          else extendMeta.value[key] = props.meta[key]
        }
        // 设置大类
        mainMeta.kind = Math.floor (mainMeta.controlType / 10 )  
      }, 300)
      
    })

    // 监听变化，设置返回 meta
    let timeout2 = null
    watch(miniMeta, () => {
      clearTimeout(timeout2)
      timeout2 = setTimeout(() => {
        // 设置返回属性
        for (const key in reMeta) {
          switch (key) {
            case 'columnId':
            case 'colName':
            case 'kind':
            case 'controlType':
              break;
            default:
              delete props.meta[key]
              break
          }
        }
        Object.assign(props.meta, miniMeta)
        // props.meta.controlType = mainMeta.controlType
      }, 100)
    })

    return {
      extendMiniMeta,
      mainMeta,
      extendMeta,
      miniMeta,
      tabComp,
      tabClick,
      baseFormProps,
      baseDefaultValue,
      extendProps

    }
  }

})
</script>